﻿
using System;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Microsoft.Win32;

namespace WindowsAPI.Hooks
{
    [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("000214FB-0000-0000-C000-000000000046")]
    public interface IShellExecuteHook
    {
        [PreserveSig]
        ShellExecuteResult Execute(ShellExecuteInfo pei);
    }

    [Guid("000A25D4-7280-4D5F-B512-97E0E49168A4")]
    [ComVisible(true)]
    public class SimpleExt : IShellExecuteHook
    {
        #region Implementation of IShellExecuteHook

        public ShellExecuteResult Execute(ShellExecuteInfo pei)
        {
            try
            {
                switch(pei.lpFile)
                {
                    case "msgbox":
                        MessageBox.Show(pei.lpParameters);
                        return ShellExecuteResult.Ok;
                    case "time":
                        MessageBox.Show(DateTime.Now.ToString(CultureInfo.InvariantCulture));
                        return ShellExecuteResult.Ok;
                    default:
                        if(pei.lpFile.Contains(".txt"))
                        {
                            MessageBox.Show(string.Format("You can not open text files! Acces to file: {0} denied!", pei.lpFile));
                            return ShellExecuteResult.Ok;
                        }
                        break;
                }
            }
            catch(FormatException) { return ShellExecuteResult.False; }
            catch(Exception ex) { MessageBox.Show(ex.Message); }
            return ShellExecuteResult.False;
        }

        #endregion

        public static void Register(string path, string clsid)
        {
            try
            {
                var mAsm = Assembly.LoadFrom(path);
                var mReg = new RegistrationServices();
                mReg.RegisterAssembly(mAsm, 0);
                const string RegPath = @"Software\Microsoft\Windows\CurrentVersion\Explorer\ShellExecuteHooks";
                var key = Registry.LocalMachine.OpenSubKey(RegPath, true);
                Debug.Assert(key != null, "key != null");
                key.SetValue(clsid, "SimpleExtension");
                key.Close();
            }
            catch(Exception ex) { MessageBox.Show(ex.Message); }
        }

        public static void Unregister(string path, string clsid)
        {
            try
            {
                var mAsm = Assembly.LoadFile(path);
                var mReg = new RegistrationServices();
                mReg.UnregisterAssembly(mAsm);
                const string RegPath = @"Software\Microsoft\Windows\CurrentVersion\Explorer\ShellExecuteHooks";
                var key = Registry.LocalMachine.OpenSubKey(RegPath, true);
                Debug.Assert(key != null, "key != null");
                key.DeleteValue(clsid);
                key.Close();
            }
            catch(Exception ex) { MessageBox.Show(ex.Message); }
        }
    }

    public enum ShellExecuteResult { False = 0, Ok = 1 }
}